package ri.core;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopScoreDocCollector;

import ri.util.ScoreUser;
import twitter4j.TwitterException;
import util.InterfaceTwitter;

public class IRInfo {
	
	private static IRInfo instance;
	private InterfaceTwitter twitter;
	
	public IRInfo(InterfaceTwitter i) {
		twitter = i;
	}

	public static IRInfo getInstance(InterfaceTwitter i) {
		if(instance == null)
			instance = new IRInfo(i);
		return instance;
	}
	
	private List<ScoreUser> calcular(String username, int top){
		HashMap<Integer, Float> map = new HashMap<Integer, Float>();
		
		TopScoreDocCollector scoreRecebidas = TopScoreDocCollector.create(top, true);
		Corpus.getInstance().searchTF(Corpus.NAME_FIELD_MENCOES_RECEBIDAS, username, scoreRecebidas);
		
		for(ScoreDoc s : scoreRecebidas.topDocs().scoreDocs){
			Float last = map.get(s.doc);
			last = (float) (last == null ? 0.0 : last);  
			Float novo = (float) (last + (s.score * 0.3));
			map.put(s.doc, novo);
		}
		
		TopScoreDocCollector scoreFeitas = TopScoreDocCollector.create(top, true);
		Corpus.getInstance().searchTF(Corpus.NAME_FIELD_MENCOES_FEITAS, username, scoreFeitas);
		
		for(ScoreDoc s : scoreFeitas.topDocs().scoreDocs){
			Float last = map.get(s.doc);
			last = (float) (last == null ? 0.0 : last);  
			Float novo = (float) (last + (s.score * 0.7));
			map.put(s.doc, novo);
		}
		
		ArrayList<ScoreUser> score = new ArrayList<ScoreUser>(); 
		
		for(Integer i : map.keySet()){
			score.add(new ScoreUser(i, map.get(i)));
		}
		
		Collections.sort(score);
		
		return score;
	}
	
	public List<String> recomendacoes(int top) throws IllegalStateException, TwitterException{
		String username = twitter.getLoginUsuario();
		List<ScoreUser> score = calcular(username, top);
		LinkedList<String> list = new LinkedList<String>();
		for(ScoreUser s : score){
			try {
				String name = Corpus.getInstance().getIndexReader().document(s.id).get(Corpus.NAME_FIELD_USERNAME);
				list.add(name);
			} catch (CorruptIndexException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return list;
	}
	
	public void atualizarIR() throws IllegalStateException, TwitterException{
		InterfaceTwitter i = twitter;
		String user = i.getLoginUsuario();
		i.calculaMapaMencoesRecebidasComDatas();
		i.calculaMapaMencoesFeitasComData();
		HashMap<String, Date[]> mencoesFeitas = i.retornaMapaMencoesFeitasDatas();
		HashMap<String, Date[]> mencoesRecebidas = i.retornaMapaMencoesRecebidasComDatas();
		ArrayList<String> feitas = new ArrayList<String>();
		ArrayList<String> recebidas = new ArrayList<String>();
		Date dateLast = Corpus.getInstance().lastUpdate(user);
		Date newDateLast = dateLast;
		
		for(String s : mencoesFeitas.keySet()){
			for(Date date : mencoesFeitas.get(s)){
				
				if(dateLast == null || dateLast.before(date)){
					feitas.add(s);
				}
				
				if(newDateLast == null){
					newDateLast = date;
				}else if(date.after(newDateLast)){
					newDateLast = date;
				}
			}
		}
		
		for(String s : mencoesRecebidas.keySet()){
			for(Date date : mencoesRecebidas.get(s)){
				
				if(dateLast == null || dateLast.before(date)){
					recebidas.add(s);
				}
				
				if(newDateLast == null){
					newDateLast = date;
				}else if(date.after(newDateLast)){
					newDateLast = date;
				}
			}
		}
		
		System.out.println("Feitas " + feitas.size());
		System.out.println("Recebidas " + recebidas.size());
		
		Corpus.getInstance().updateDatas(user, feitas, recebidas, newDateLast);		
	}
	
	public static void main(String[] args) throws Exception {
		InterfaceTwitter i = InterfaceTwitter.getInstance();
		i.setAuthConsumerTwitter();
		i.recuperaRequest();
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		while (null == i.getAccessToken()) {
		      System.out.println("Open the following URL and grant access to your account:");
		      System.out.println(i.geraURL());
		      System.out.print("Enter the PIN(if aviailable) or just hit enter.[PIN]:");
		      String pin = br.readLine();
		      i.returnAccess(pin);
		}
		i.autentica();
		
		IRInfo ir = getInstance(i);
		ir.atualizarIR();
		System.out.println(ir.recomendacoes(10));
	}
	
}
